use std::error::Error;
use std::fs;
use colored::Colorize;

pub struct Config<'a> {
    keyword: &'a str,
    filename: &'a str,
    ignore_case: bool,
}

impl Config<'_> {
    pub fn parse(args: &[String]) -> Result<Config, &'static str> {
        if args.len() < 2 {
            return Err("please input enough parameter!");
        }

        return Ok(Config {
            keyword: &args[0],
            filename: &args[1],
            ignore_case: &args[2] == "true",
        });
    }
}

pub fn search(config: Config) -> Result<(), Box<dyn Error>> {
    let keywords = config.keyword;
    let txt = fs::read_to_string(config.filename)?;

    let mut i = 0;
    let mut searched: bool = false;

    for line in txt.lines() {
        i = i + 1;

        let find_index;
        if config.ignore_case {
            find_index = line.to_lowercase().find(&keywords.to_lowercase());
        } else {
            find_index = line.find(keywords);
        }

        if !find_index.is_none() {
            searched = true;
            let index = find_index.unwrap();
            let preffix_line = &line[0..index];
            let suffix_line = &line[index + keywords.len()..];
            let key = &line[index..index + keywords.len()];
            println!("at line:{} -> {}{}{}\n", &(i.to_string()).red(), preffix_line, key.green(), suffix_line);
        }
    }
    if !searched {
        println!("{}", "sorry, nothing matched!".red());
    }

    Ok(())
}